package com.lt.schoolchat.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.green.model.v20180509.VideoAsyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @description:
 * @author: ~Teng~
 * @date: 2023/6/1 11:07
 */
@Data
@Component
@PropertySource("classpath:aliyun.properties")
@ConfigurationProperties(prefix = "aliyun")
public class GreenVideoScan {
    private String accessKeyId;
    private String secret;
    private String scenes;

    private static Map<String, String> labelsMap = new HashMap<>();

    static {
        labelsMap.put("normal", "正常文本");
        labelsMap.put("sexy", "性感");
        labelsMap.put("porn", "色情");
        labelsMap.put("bloody", "血腥");
        labelsMap.put("explosion", "爆炸烟光");
        labelsMap.put("outfit", "特殊装束");
        labelsMap.put("logo", "特殊装束");
        labelsMap.put("weapon", "武器");
        labelsMap.put("politics", "涉政");
        labelsMap.put("violence", "打斗");
        labelsMap.put("crowd", "聚众");
        labelsMap.put("parade", "游行");
        labelsMap.put("carcrash", "车祸现场");
        labelsMap.put("flag", "旗帜");
        labelsMap.put("location", "地标");
        labelsMap.put("drug", "涉毒");
        labelsMap.put("gamble", "赌博");
        labelsMap.put("others", "其他");
        labelsMap.put("abuse", "文字含辱骂内容");
        labelsMap.put("terrorism", "文字含暴恐内容");
        labelsMap.put("contraband", "文字含违禁内容");
        labelsMap.put("npx", "牛皮藓广告");
        labelsMap.put("qrcode", "含二维码");
        labelsMap.put("programCode", "含小程序码");
        labelsMap.put("meaningless", "图中无内容");
        labelsMap.put("PIP", "画中画");
        labelsMap.put("drivelive", "车内直播");
        labelsMap.put("TV", "受管控的logo");
        labelsMap.put("trademark", "含商标");
    }

    /**
     * 视频内容审核
     */
    public Map imageUrlScan(String videoUrl) throws Exception {
        IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKeyId, secret);
        DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
        // 注意：此处实例化的client尽可能重复使用，提升检测性能。避免重复建立连接。
        IAcsClient client = new DefaultAcsClient(profile);

        VideoAsyncScanRequest videoAsyncScanRequest = new VideoAsyncScanRequest();
        videoAsyncScanRequest.setAcceptFormat(FormatType.JSON); // 指定API返回格式。
        videoAsyncScanRequest.setMethod(com.aliyuncs.http.MethodType.POST); // 指定请求方法。

        List<Map<String, Object>> tasks = new ArrayList<>();
        Map<String, Object> task = new LinkedHashMap<>();
        task.put("dataId", UUID.randomUUID().toString());
        task.put("url", videoUrl);

        tasks.add(task);
        /**
         * 设置要检测的场景。计费是依据此处传递的场景计算。
         * 视频默认1秒截取一帧，您可以自行控制截帧频率。收费按照视频的截帧数量以及每一帧的检测场景计算。
         * 举例：1分钟的视频截帧60张，检测色情（对应场景参数porn）和暴恐涉政（对应场景参数terrorism）2个场景，收费按照60张色情+60张暴恐涉政进行计费。
         */
        JSONObject data = new JSONObject();
        data.put("scenes", Arrays.asList(scenes.split(",")));
        data.put("tasks", tasks);
//        data.put("callback", "http://www.aliyundoc.com/xxx.json");
//        data.put("seed", "yourPersonalSeed");

        videoAsyncScanRequest.setHttpContent(data.toJSONString().getBytes("UTF-8"), "UTF-8", FormatType.JSON);

        /**
         * 请务必设置超时时间。
         */
        videoAsyncScanRequest.setConnectTimeout(3000);
        videoAsyncScanRequest.setReadTimeout(6000);
        Map<String, String> resultMap = new HashMap<>();
        try {
            HttpResponse httpResponse = client.doAction(videoAsyncScanRequest);

            if (httpResponse.isSuccess()) {
                JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
                int requestCode = scrResponse.getIntValue("code");
                // 每一个视频的检测结果。
                JSONArray taskResults = scrResponse.getJSONArray("data");
                if (200 == requestCode) {
                    for (Object taskResult : taskResults) {
                        // 单个视频的处理结果。
                        int taskCode = ((JSONObject) taskResult).getIntValue("code");
                        // 图片要检测的场景的处理结果, 如果是多个场景，则会有每个场景的结果
                        com.alibaba.fastjson.JSONArray sceneResults = ((com.alibaba.fastjson.JSONObject) taskResult).getJSONArray("results");
                        if (200 == taskCode) {
                            // 保存taskId用于轮询结果。
                            System.out.println(((JSONObject) taskResult).getString("taskId"));
                            for (Object sceneResult : sceneResults) {
                                String scene = ((com.alibaba.fastjson.JSONObject) sceneResult).getString("scene");
                                String label = ((com.alibaba.fastjson.JSONObject) sceneResult).getString("label");
                                String suggestion = ((com.alibaba.fastjson.JSONObject) sceneResult).getString("suggestion");
                                // 根据scene和suggetion做相关处理
                                if (!"pass".equals(suggestion)) {
                                    resultMap.put("suggestion", suggestion);
                                    resultMap.put("label", label);
                                    String reason = labelsMap.get(label);
                                    resultMap.put("reason", reason);
                                    resultMap.put("scene", scene);
                                    return resultMap;
                                }
                            }
                        } else {
                            // 单个视频处理失败，原因视具体的情况详细分析。
                            System.out.println("task process fail. task response:" + JSON.toJSONString(taskResult));
                            return null;
                        }
                    }
                    resultMap.put("suggestion", "pass");
                    return resultMap;
                } else {
                    /**
                     * 表明请求整体处理失败，原因视具体的情况详细分析。
                     */
                    System.out.println("the whole scan request failed. response:" + JSON.toJSONString(scrResponse));
                    return null;
                }
            } else {
                System.out.println("response not success. status:" + httpResponse.getStatus());
            }
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return null;
    }
}
